/** <a href="http://www.cpupk.com/decompiler">Eclipse Class Decompiler</a> plugin, Copyright (c) 2017 Chen Chao. **/
package com.minierp.service.impl;

import com.minierp.bean.PurchaseBillBean;
import com.minierp.bean.PurchaseBillItemBean;
import com.minierp.bean.UserBean;
import com.minierp.dao.AdjustBillDao;
import com.minierp.dao.BankAccountBalanceDao;
import com.minierp.dao.BankAccountDetailDao;
import com.minierp.dao.FinanceDetailDao;
import com.minierp.dao.IdGenerator;
import com.minierp.dao.PayBillDao;
import com.minierp.dao.PurchaseBillDao;
import com.minierp.dao.PurchaseBillItemDao;
import com.minierp.dao.SerialNumberDao;
import com.minierp.dao.StockBalanceDao;
import com.minierp.dao.StockDao;
import com.minierp.err.DataChangedException;
import com.minierp.err.NotAllowException;
import com.minierp.err.StockNoEnoughException;
import com.minierp.helper.EncCommonHelper;
import com.minierp.helper.PageHelper;
import com.minierp.model.CodeRule;
import com.minierp.model.EnterpriseInfo;
import com.minierp.model.Establishment;
import com.minierp.model.FinanceDetail;
import com.minierp.model.InOutHistory;
import com.minierp.model.PurchaseBill;
import com.minierp.model.PurchaseBillExt;
import com.minierp.model.PurchaseBillItem;
import com.minierp.model.Stock;
import com.minierp.model.SystemLog;
import com.minierp.service.PurchaseBillService;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletRequest;

public class PurchaseBillServiceImpl implements PurchaseBillService {
	public void txInsert(PurchaseBillBean form, String exam, UserBean ub,
			EnterpriseInfo ent, PurchaseBillDao purchaseBillDao,
			PurchaseBillItemDao purchaseBillItemDao,
			BankAccountBalanceDao bankAccountBalanceDao, StockDao stockDao,
			StockBalanceDao stockBalanceDao, SerialNumberDao serialNumberDao,
			IdGenerator idGenerator) throws StockNoEnoughException, Exception {
		PurchaseBill obj = form.getPurchaseBill();
		obj.setCreateTime(new Date());
		obj.setId(idGenerator.getId(PurchaseBill.class.getName()));
		if (!form.getCodeRule().getGenerateRule().equals("MANUAL")) {
			obj.setBillCode(PageHelper.generateCode(serialNumberDao, form
					.getCodeRule(), "", form.getPurchaseBill().getTallySetId()));

			for (PurchaseBill be = purchaseBillDao.get(obj.getBillCode()); be != null; be = purchaseBillDao
					.get(obj.getBillCode())) {
				obj.setBillCode(PageHelper.generateCode(serialNumberDao, form
						.getCodeRule(), "", form.getPurchaseBill()
						.getTallySetId()));
			}
		}

		this.setCost(form);
		purchaseBillDao.save(obj);
		PurchaseBillExt be1 = new PurchaseBillExt();
		boolean updateStock = false;
		be1.setId(obj.getId());
		if (exam != null && exam.equals("1")) {
			be1.setExamined("Y");
			be1.setPaiedCost(obj.getImprest());
			if (obj.getCost().compareTo(be1.getPaiedCost()) == 0) {
				be1.setPaied("Y");
			}

			be1.setExamineTime(new Date());
			be1.setExaminerId(ub.getUser().getStafferId());
			be1.setExaminerName(ub.getStaffer().getStafferName());
			if (ent.getPurcStoc().equals("Y")) {
				be1.setStoc("Y");
				be1.setStocDate(obj.getPurchaseDate());
				updateStock = true;
			} else {
				be1.setStoc("N");
				updateStock = false;
			}
		}

		purchaseBillDao.save(be1);
		this.saveItems(obj, updateStock, be1.getStocDate(),
				form.getProviderName(), form.getItems(), purchaseBillItemDao,
				stockDao, stockBalanceDao, idGenerator);
		if (be1.getExamined().equals("Y")
				&& obj.getImprest().compareTo(new BigDecimal(0)) != 0) {
			BigDecimal est = obj.getImprest();
			String costType = "采购进货预付";
			if (obj.getBillType().equals("BACK")) {
				costType = "采购退货预收";
				est = (new BigDecimal(0)).subtract(est);
			}

			String mark = form.getProviderName();
			if (obj.getContent() != null && !obj.getContent().equals("")) {
				mark = mark + "," + obj.getContent();
			}

			PageHelper.updateBankAccount(obj.getBankAccountId(),
					obj.getTallySetId(), obj.getId(), est,
					obj.getPurchaseDate(), be1.getExamineTime(),
					obj.getBillCode(), "PURCHASE_BILL", "", costType, "P",
					obj.getManagerName(), mark, "PURCHASE", "SAVE_EXAM", false,
					(BankAccountDetailDao) null, bankAccountBalanceDao,
					idGenerator);
		}

		if (be1.getExamined().equals("Y")) {
			Establishment est1 = (Establishment) purchaseBillDao.get(
					Establishment.class, obj.getProviderId());
			if (est1 != null
					&& (est1.getBusTime() == null || est1.getBusTime().before(
							obj.getPurchaseDate()))) {
				est1.setBusTime(obj.getPurchaseDate());
				purchaseBillDao.update(est1);
			}
		}

		if (be1.getExamined().equals("Y")) {
			this.insertFinanceDetail(obj, purchaseBillDao, idGenerator);
		}

	}

	private void setCost(PurchaseBillBean form) {
		List items = form.getItems();
		BigDecimal cost = new BigDecimal(0);

		for (int i = 0; i < items.size(); ++i) {
			PurchaseBillItemBean bean = (PurchaseBillItemBean) items.get(i);
			if (!bean.getStatus().equals("DELETE")) {
				bean.getPurchaseBillItem()
						.setCost(
								bean.getPurchaseBillItem()
										.getAmount()
										.multiply(
												bean.getPurchaseBillItem()
														.getUnitPrice())
										.setScale(2, 4));
				cost = cost.add(bean.getPurchaseBillItem().getCost());
			}
		}

		form.getPurchaseBill().setCost(cost);
	}

	public void txInsertForBegiImpo(PurchaseBill obj, CodeRule cr,
			PurchaseBillItem item, UserBean ub, String estName,
			EnterpriseInfo ent, PurchaseBillDao purchaseBillDao,
			StockDao stockDao, StockBalanceDao stockBalanceDao,
			SerialNumberDao serialNumberDao, IdGenerator idGenerator)
			throws Exception {
		obj.setCreateTime(new Date());
		obj.setId(idGenerator.getId(PurchaseBill.class.getName()));
		if (cr.getGenerateRule().equals("MANUAL")) {
			throw new NotAllowException("采购单编号规则必须设置成自动产生！");
		} else {
			obj.setBillCode(PageHelper.generateCode(serialNumberDao, cr, "",
					obj.getTallySetId()));

			for (PurchaseBill be = purchaseBillDao.get(obj.getBillCode()); be != null; be = purchaseBillDao
					.get(obj.getBillCode())) {
				obj.setBillCode(PageHelper.generateCode(serialNumberDao, cr,
						"", obj.getTallySetId()));
			}

			purchaseBillDao.save(obj);
			PurchaseBillExt be1 = new PurchaseBillExt();
			be1.setId(obj.getId());
			be1.setExamined("Y");
			be1.setExamineTime(new Date());
			be1.setExaminerId(ub.getUser().getStafferId());
			be1.setExaminerName(ub.getStaffer().getStafferName());
			be1.setStoc("N");
			purchaseBillDao.save(be1);
			item.setId(idGenerator.getId(PurchaseBillItem.class.getName()));
			item.setBillId(obj.getId());
			purchaseBillDao.save(item);
			Establishment est = (Establishment) purchaseBillDao.get(
					Establishment.class, obj.getProviderId());
			if (est != null
					&& (est.getBusTime() == null || est.getBusTime().before(
							obj.getPurchaseDate()))) {
				est.setBusTime(obj.getPurchaseDate());
				purchaseBillDao.update(est);
			}

			this.insertFinanceDetail(obj, purchaseBillDao, idGenerator);
		}
	}

	private void insertFinanceDetail(PurchaseBill obj,
			PurchaseBillDao purchaseBillDao, IdGenerator idGenerator) {
		BigDecimal remCost;
		BigDecimal conCost;
		BigDecimal rpCost;
		if (obj.getBillType().equals("BUY")) {
			remCost = obj.getCost().subtract(obj.getImprest());
			conCost = obj.getCost();
			rpCost = obj.getImprest();
		} else {
			remCost = (new BigDecimal(0)).subtract(obj.getCost().subtract(
					obj.getImprest()));
			conCost = (new BigDecimal(0)).subtract(obj.getCost());
			rpCost = (new BigDecimal(0)).subtract(obj.getImprest());
		}

		FinanceDetail fd = new FinanceDetail();
		fd.setId(idGenerator.getId(FinanceDetail.class.getName()));
		fd.setBillDate(obj.getPurchaseDate());
		fd.setBillId(obj.getId());
		fd.setBillType("PURCHASE_BILL");
		fd.setRemCost(remCost);
		fd.setConCost(conCost);
		fd.setRpCost(rpCost);
		fd.setEstId(obj.getProviderId());
		fd.setFinanceType("P");
		fd.setTallySetId(obj.getTallySetId());
		purchaseBillDao.save(fd);
	}

	public void txUpdate(PurchaseBillBean form, String exam, UserBean ub,
			EnterpriseInfo ent, PurchaseBillDao purchaseBillDao,
			PurchaseBillItemDao purchaseBillItemDao, PayBillDao payBillDao,
			AdjustBillDao adjustBillDao,
			BankAccountBalanceDao bankAccountBalanceDao, StockDao stockDao,
			StockBalanceDao stockBalanceDao, IdGenerator idGenerator)
			throws Exception {
		PurchaseBill obj = form.getPurchaseBill();
		Object[] sv = purchaseBillDao.getStatusValues(obj.getId());
		if (sv == null) {
			throw new Exception("Can\'t get status values for in bill:"
					+ obj.getId());
		} else {
			long existSycVal = ((Date) sv[0]).getTime();
			PurchaseBillExt be = (PurchaseBillExt) purchaseBillDao.get(
					PurchaseBillExt.class, obj.getId());
			String billName;
			if (obj.getBillType().equals("BACK")) {
				billName = "退货单";
			} else {
				billName = "采购单";
			}

			if (existSycVal != form.getSychronizeValue()) {
				throw new DataChangedException(billName
						+ "已被其他操作修改，请关闭页面再打开后重新操作！");
			} else if (be.getEnabled().equals("N")) {
				throw new NotAllowException(billName + "已作废，不能修改！");
			} else if (be.getExamined().equals("Y")) {
				throw new NotAllowException(billName + "已审核，不能修改！");
			} else {
				this.setCost(form);
				obj.setUpdateTime(new Date());
				purchaseBillDao.update(obj);
				boolean updateStock = false;
				if (exam != null && exam.equals("1")) {
					be.setExamined("Y");
					be.setPaiedCost(obj.getImprest());
					if (obj.getCost().compareTo(be.getPaiedCost()) == 0) {
						be.setPaied("Y");
					}

					be.setExamineTime(new Date());
					be.setExaminerId(ub.getUser().getStafferId());
					be.setExaminerName(ub.getStaffer().getStafferName());
					if (ent.getPurcStoc().equals("Y")) {
						be.setStoc("Y");
						be.setStocDate(obj.getPurchaseDate());
						updateStock = true;
					} else {
						be.setStoc("N");
						updateStock = false;
					}
				}

				purchaseBillDao.update(be);
				this.saveItems(obj, updateStock, be.getStocDate(),
						form.getProviderName(), form.getItems(),
						purchaseBillItemDao, stockDao, stockBalanceDao,
						idGenerator);
				if (be.getExamined().equals("Y")
						&& obj.getImprest().compareTo(new BigDecimal(0)) != 0) {
					BigDecimal est = obj.getImprest();
					String costType = "采购进货预付";
					if (obj.getBillType().equals("BACK")) {
						est = (new BigDecimal(0)).subtract(est);
						costType = "采购退货预付";
					}

					String providerName = "";
					Establishment est1 = (Establishment) bankAccountBalanceDao
							.get(Establishment.class, obj.getProviderId());
					if (est1 != null) {
						providerName = est1.getEstName();
						if (obj.getContent() != null
								&& !obj.getContent().equals("")) {
							providerName = providerName + ","
									+ obj.getContent();
						}
					}

					PageHelper.updateBankAccount(obj.getBankAccountId(),
							obj.getTallySetId(), obj.getId(), est,
							obj.getPurchaseDate(), be.getExamineTime(),
							obj.getBillCode(), "PURCHASE_BILL", "", costType,
							"P", obj.getManagerName(), providerName,
							"PURCHASE", "SAVE_EXAM", false,
							(BankAccountDetailDao) null, bankAccountBalanceDao,
							idGenerator);
				}

				if (be.getExamined().equals("Y")) {
					Establishment est2 = (Establishment) purchaseBillDao.get(
							Establishment.class, obj.getProviderId());
					if (est2 != null
							&& (est2.getBusTime() == null || est2.getBusTime()
									.before(obj.getPurchaseDate()))) {
						est2.setBusTime(obj.getPurchaseDate());
						purchaseBillDao.update(est2);
					}
				}

				if (be.getExamined().equals("Y")) {
					this.insertFinanceDetail(obj, purchaseBillDao, idGenerator);
				}

			}
		}
	}

	private void saveItems(PurchaseBill purchaseBill, boolean updateStock,
			Date stocDate, String estName, List<?> items,
			PurchaseBillItemDao purchaseBillItemDao, StockDao stockDao,
			StockBalanceDao stockBalanceDao, IdGenerator idGenerator)
			throws StockNoEnoughException, ParseException {
		int newNum = 0;

		for (int curItemId = 0; curItemId < items.size(); ++curItemId) {
			PurchaseBillItemBean bean = (PurchaseBillItemBean) items
					.get(curItemId);
			if (bean.getStatus().equals("NEW")) {
				++newNum;
			}
		}

		long arg14 = 0L;
		if (newNum > 0) {
			arg14 = idGenerator.getId(PurchaseBillItem.class.getName(), newNum);
		}

		for (int i = 0; i < items.size(); ++i) {
			PurchaseBillItemBean bean1 = (PurchaseBillItemBean) items.get(i);
			bean1.getPurchaseBillItem().setBillId(purchaseBill.getId());
			if (bean1.getStatus().equals("DELETE")) {
				if (bean1.getPurchaseBillItem().getId() != 0L) {
					purchaseBillItemDao.delete(bean1.getPurchaseBillItem()
							.getId());
				}
			} else if (bean1.getStatus().equals("EDIT")) {
				purchaseBillItemDao.update(bean1.getPurchaseBillItem());
			} else if (bean1.getStatus().equals("NEW")) {
				bean1.getPurchaseBillItem().setId(arg14);
				purchaseBillItemDao.save(bean1.getPurchaseBillItem());
				++arg14;
			}
		}

		if (updateStock) {
			this.updateStock(purchaseBill,
					purchaseBillItemDao.getList(purchaseBill.getId()),
					stockDao, stockBalanceDao, idGenerator, stocDate, estName,
					"SAVE_EXAM", "");
		}

	}

	private void updateStock(PurchaseBill b, List items, StockDao stockDao,
			StockBalanceDao stockBalanceDao, IdGenerator idGenerator,
			Date stocDate, String estName, String operType, String stafName)
			throws StockNoEnoughException, ParseException {
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
		BigDecimal zero = new BigDecimal(0);

		for (int j = 0; j < items.size(); ++j) {
			PurchaseBillItem it = (PurchaseBillItem) items.get(j);
			BigDecimal iohUp = it.getUnitPrice();
			BigDecimal iohAmount;
			BigDecimal iohCost;
			if (b.getBillType().equals("BUY")) {
				if (!operType.equals("SAVE_EXAM") && !operType.equals("EXAM")
						&& !operType.equals("STOC")) {
					iohAmount = zero.subtract(it.getAmount());
					iohCost = zero.subtract(it.getCost());
				} else {
					iohAmount = it.getAmount();
					iohCost = it.getCost();
				}
			} else if (!operType.equals("SAVE_EXAM")
					&& !operType.equals("EXAM") && !operType.equals("STOC")) {
				iohAmount = it.getAmount();
				iohCost = it.getCost();
			} else {
				iohAmount = zero.subtract(it.getAmount());
				iohCost = zero.subtract(it.getCost());
			}

			Stock s = stockDao.get(it.getProductId(), b.getStorehouseId());
			BigDecimal currentAmount;
			if (s == null) {
				currentAmount = new BigDecimal(0);
				s = new Stock();
				s.setAmount(iohAmount);
				s.setCost(iohCost);
				s.setUnitPrice(iohUp);
				s.setId(idGenerator.getId(Stock.class.getName()));
				s.setProductId(it.getProductId());
				s.setStorehouseId(b.getStorehouseId());
				stockDao.save(s);
			} else {
				currentAmount = s.getAmount();
				s.setAmount(s.getAmount().add(iohAmount));
				s.setCost(s.getCost().add(iohCost));
				if (s.getAmount().compareTo(zero) != 0) {
					s.setUnitPrice(s.getCost().divide(s.getAmount(), 4, 4));
				}

				stockDao.update(s);
			}

			if (s.getAmount().compareTo(new BigDecimal(0)) == -1) {
				String arg19 = PageHelper.stockNotEnoughMeg(stockDao,
						it.getProductId(), currentAmount, s.getAmount());
				throw new StockNoEnoughException(arg19);
			}

			PageHelper.updateStockBalance(stockBalanceDao, it.getProductId(),
					iohAmount, stocDate, iohCost, b.getStorehouseId(),
					idGenerator, "ADD");
			if (operType.equals("UN_EXAM") || operType.equals("CANC")
					|| operType.equals("UN_STOC")) {
				stockDao.updateIohLogData("PURC_BILL", b.getId());
			}

			InOutHistory h = new InOutHistory();
			h.setBillId(b.getId());
			h.setBillCode(b.getBillCode());
			h.setBillDate(stocDate);
			h.setProId(it.getProductId());
			h.setStoId(b.getStorehouseId());
			h.setBillType("PURC_BILL");
			h.setId(idGenerator.getId(InOutHistory.class.getName()));
			h.setOperType(operType);
			h.setIoType("IN");
			h.setRequType("PROVIDER");
			h.setRequId(b.getProviderId());
			h.setRequName(estName);
			h.setUnitPrice(iohUp);
			h.setCost(iohCost);
			h.setAmount(iohAmount);
			h.setStorAmou(s.getAmount());
			h.setStorCost(s.getCost());
			h.setStorUp(s.getUnitPrice());
			if (operType.equals("UN_EXAM")) {
				h.setLogData("Y");
				h.setMark(stafName + "于" + sf.format(h.getIoTime()) + "反审核单据");
			} else if (operType.equals("CANC")) {
				h.setLogData("Y");
				h.setMark(stafName + "于" + sf.format(h.getIoTime()) + "作废单据");
			} else if (operType.equals("UN_STOC")) {
				h.setLogData("Y");
				h.setMark(stafName + "于" + sf.format(h.getIoTime()) + "取消入库");
			} else if (operType.equals("STOC")) {
				h.setLogData("N");
				h.setMark(stafName + "于" + sf.format(h.getIoTime()) + "手工入库");
			} else {
				h.setLogData("N");
				h.setMark(it.getMark());
			}

			stockDao.save(h);
		}

	}

	public void txExamine(HttpServletRequest request, long id,
			PurchaseBillDao purchaseBillDao,
			PurchaseBillItemDao purchaseBillItemDao, PayBillDao payBillDao,
			AdjustBillDao adjustBillDao,
			BankAccountBalanceDao bankAccountBalanceDao, StockDao stockDao,
			StockBalanceDao stockBalanceDao, IdGenerator idGenerator,
			UserBean ub) throws StockNoEnoughException, Exception {
		PurchaseBill b = (PurchaseBill) purchaseBillDao.get(PurchaseBill.class,
				id);
		PurchaseBillExt be = (PurchaseBillExt) purchaseBillDao.get(
				PurchaseBillExt.class, id);
		if (b != null && be.getEnabled().equals("Y")
				&& be.getExamined().equals("N")) {
			String priCode = "PURC_BUY_EXAM";
			if (b.getBillType().equals("BACK")) {
				priCode = "PURC_BACK_EXAM";
			}

			if (!EncCommonHelper.checkPrivilege(request, priCode)) {
				throw new Exception("您还没有此功能的使用权限，请确认返回！");
			}

			EnterpriseInfo ent = EncCommonHelper.getEnterpriseInfo(request);
			be.setPaiedCost(b.getImprest());
			if (b.getCost().subtract(be.getPaiedCost())
					.compareTo(new BigDecimal(0)) == 0) {
				be.setPaied("Y");
			}

			be.setExamined("Y");
			be.setExamineTime(new Date());
			be.setExaminerId(ub.getStaffer().getId());
			be.setExaminerName(ub.getStaffer().getStafferName());
			if (ent.getPurcStoc().equals("Y")) {
				be.setStoc("Y");
				be.setStocDate(b.getPurchaseDate());
			} else {
				be.setStoc("N");
			}

			purchaseBillDao.update(be);
			String providerName = "";
			String mark = "";
			Establishment est = (Establishment) bankAccountBalanceDao.get(
					Establishment.class, b.getProviderId());
			if (est != null) {
				providerName = est.getEstName();
				mark = providerName;
				if (b.getContent() != null && !b.getContent().equals("")) {
					mark = providerName + "," + b.getContent();
				}
			}

			if (ent.getPurcStoc().equals("Y")) {
				this.updateStock(b, purchaseBillItemDao.getList(b.getId()),
						stockDao, stockBalanceDao, idGenerator,
						be.getStocDate(), providerName, "EXAM", "");
			}

			BigDecimal cost = b.getImprest();
			String costType = "采购进货预付";
			if (b.getBillType().equals("BACK")) {
				cost = (new BigDecimal(0)).subtract(cost);
				costType = "采购退货预付";
			}

			PageHelper.updateBankAccount(b.getBankAccountId(),
					b.getTallySetId(), b.getId(), cost, b.getPurchaseDate(),
					be.getExamineTime(), b.getBillCode(), "PURCHASE_BILL", "",
					costType, "P", b.getManagerName(), mark, "PURCHASE",
					"EXAM", false, (BankAccountDetailDao) null,
					bankAccountBalanceDao, idGenerator);
			if (est != null
					&& (est.getBusTime() == null || est.getBusTime().before(
							b.getPurchaseDate()))) {
				est.setBusTime(b.getPurchaseDate());
				purchaseBillDao.update(est);
			}

			this.insertFinanceDetail(b, purchaseBillDao, idGenerator);
		}

	}

	public void txUnExamine(HttpServletRequest request, long id,
			PurchaseBillDao purchaseBillDao,
			PurchaseBillItemDao purchaseBillItemDao,
			BankAccountBalanceDao bankAccountBalanceDao,
			BankAccountDetailDao bankAccountDetailDao, StockDao stockDao,
			StockBalanceDao stockBalanceDao, IdGenerator idGenerator,
			FinanceDetailDao financeDetailDao, UserBean ub) throws Exception {
		PurchaseBill b = (PurchaseBill) purchaseBillDao.get(PurchaseBill.class,
				id);
		PurchaseBillExt be = (PurchaseBillExt) purchaseBillDao.get(
				PurchaseBillExt.class, id);
		if (b != null && be.getEnabled().equals("Y")
				&& be.getExamined().equals("Y")) {
			if (be.getHasPay().equals("Y")) {
				throw new NotAllowException("单据" + b.getBillCode()
						+ "已经付款，不能反审核!");
			}

			if (be.getHasAdjust().equals("Y")) {
				throw new NotAllowException("单据" + b.getBillCode()
						+ "已经调账，不能反审核!");
			}

			String priCode = "PURC_BUY_UN_EXAM";
			if (b.getBillType().equals("BACK")) {
				priCode = "PURC_BACK_UN_EXAM";
			}

			if (!EncCommonHelper.checkPrivilege(request, priCode)) {
				throw new Exception("您还没有此功能的使用权限，请确认返回！");
			}

			String stoc = be.getStoc();
			be.setExamined("N");
			be.setPaied("N");
			be.setPaiedCost(new BigDecimal(0));
			be.setExaminerId(0L);
			be.setExaminerName("");
			be.setStoc("N");
			purchaseBillDao.update(be);
			String providerName = "";
			Establishment est = (Establishment) bankAccountBalanceDao.get(
					Establishment.class, b.getProviderId());
			if (est != null) {
				providerName = est.getEstName();
			}

			if (stoc.equals("Y")) {
				this.updateStock(b, purchaseBillItemDao.getList(b.getId()),
						stockDao, stockBalanceDao, idGenerator, be
								.getStocDate(), providerName, "UN_EXAM", ub
								.getStaffer().getStafferName());
			}

			BigDecimal cost = (new BigDecimal(0)).subtract(b.getImprest());
			String costType = "采购进货预付";
			if (b.getBillType().equals("BACK")) {
				cost = (new BigDecimal(0)).subtract(cost);
				costType = "采购退货预付";
			}

			SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
			String mark = ub.getStaffer().getStafferName() + "于"
					+ sf.format(new Date()) + "反审核单据";
			PageHelper.updateBankAccount(b.getBankAccountId(),
					b.getTallySetId(), b.getId(), cost, b.getPurchaseDate(),
					new Date(), b.getBillCode(), "PURCHASE_BILL", "", costType,
					"P", b.getManagerName(), mark, "PURCHASE", "UN_EXAM", true,
					bankAccountDetailDao, bankAccountBalanceDao, idGenerator);
			financeDetailDao.delete(b.getId(), "PURCHASE_BILL");
		}

	}

	public String txCancel(HttpServletRequest request, long id, String reason,
			PurchaseBillDao purchaseBillDao,
			PurchaseBillItemDao purchaseBillItemDao,
			BankAccountBalanceDao bankAccountBalanceDao,
			BankAccountDetailDao bankAccountDetailDao, StockDao stockDao,
			StockBalanceDao stockBalanceDao, IdGenerator idGenerator,
			FinanceDetailDao financeDetailDao, UserBean ub)
			throws StockNoEnoughException, Exception {
		PurchaseBill b = (PurchaseBill) purchaseBillDao.get(PurchaseBill.class,
				id);
		PurchaseBillExt be = (PurchaseBillExt) purchaseBillDao.get(
				PurchaseBillExt.class, id);
		String msg = "";
		if (b != null && be.getEnabled().equals("Y")) {
			String billName;
			if (b.getBillType().equals("BUY")) {
				billName = "采购单";
			} else {
				billName = "退货单";
			}

			if (be.getHasPay().equals("Y")) {
				msg = billName + "已经付款，不能作废!请点击“关联单据”，先作废" + billName
						+ "的关联单据，然后再作废" + billName + "。";
			} else if (be.getHasAdjust().equals("Y")) {
				msg = billName + "已经调账，不能作废!请点击“关联单据”，先作废" + billName
						+ "的关联单据，然后再作废" + billName + "。";
			} else {
				String priCode = "PURC_BUY_CANC";
				String logActionType = "PURCHASE_BUY";
				if (b.getBillType().equals("BACK")) {
					priCode = "PURC_BACK_CANC";
					logActionType = "PURCHASE_BACK";
				}

				if (!EncCommonHelper.checkPrivilege(request, priCode)) {
					throw new Exception("Permission deny!");
				}

				be.setEnabled("N");
				be.setDisableManId(ub.getUser().getStafferId());
				purchaseBillDao.update(be);
				if (be.getExamined().equals("Y")) {
					String log = "";
					Establishment est = (Establishment) bankAccountBalanceDao
							.get(Establishment.class, b.getProviderId());
					if (est != null) {
						log = est.getEstName();
					}

					if (be.getStoc().equals("Y")) {
						this.updateStock(b, purchaseBillItemDao.getList(b
								.getId()), stockDao, stockBalanceDao,
								idGenerator, be.getStocDate(), log, "CANC", ub
										.getStaffer().getStafferName());
					}

					BigDecimal cost = (new BigDecimal(0)).subtract(b
							.getImprest());
					String costType = "采购进货预付";
					if (b.getBillType().equals("BACK")) {
						cost = (new BigDecimal(0)).subtract(cost);
						costType = "采购退货预付";
					}

					SimpleDateFormat sf = new SimpleDateFormat(
							"yyyy-MM-dd HH:mm");
					String mark = ub.getStaffer().getStafferName() + "于"
							+ sf.format(new Date()) + "作废单据";
					PageHelper.updateBankAccount(b.getBankAccountId(),
							b.getTallySetId(), b.getId(), cost,
							b.getPurchaseDate(), new Date(), b.getBillCode(),
							"PURCHASE_BILL", "", costType, "P",
							b.getManagerName(), mark, "PURCHASE", "CANC", true,
							bankAccountDetailDao, bankAccountBalanceDao,
							idGenerator);
				}

				if (be.getExamined().equals("Y")) {
					financeDetailDao.delete(b.getId(), "PURCHASE_BILL");
				}

				SystemLog log1 = new SystemLog();
				log1.setId(idGenerator.getId(SystemLog.class.getName()));
				log1.setActionCode(logActionType);
				log1.setLogType("CANCEL_LOG");
				log1.setCreaterId(ub.getStaffer().getId());
				log1.setCreaterName(ub.getStaffer().getStafferName());
				log1.setDepName(ub.getDepName());
				log1.setDepId(ub.getStaffer().getDepartmentId());
				log1.setStatus("S");
				log1.setUserName(ub.getUser().getUserName());
				log1.setIp(b.getBillCode());
				log1.setMark("");
				log1.setRelId(id);
				log1.setCancelReason(reason);
				log1.setTallySetId(b.getTallySetId());
				purchaseBillDao.save(log1);
				msg = "作废成功!";
			}
		}

		return msg;
	}

	public void txStoc(HttpServletRequest request, long id, Date stocDate,
			PurchaseBillItemDao purchaseBillItemDao, StockDao stockDao,
			StockBalanceDao stockBalanceDao, IdGenerator idGenerator,
			UserBean ub) throws StockNoEnoughException, Exception {
		PurchaseBill b = (PurchaseBill) purchaseBillItemDao.get(
				PurchaseBill.class, id);
		PurchaseBillExt be = (PurchaseBillExt) purchaseBillItemDao.get(
				PurchaseBillExt.class, id);
		if (b != null && be.getEnabled().equals("Y")
				&& be.getExamined().equals("Y") && be.getStoc().equals("N")) {
			String priCode = "PURC_BUY_STOC";
			if (b.getBillType().equals("BACK")) {
				priCode = "PURC_BACK_STOC";
			}

			if (!EncCommonHelper.checkPrivilege(request, priCode)) {
				throw new Exception("Permission deny!");
			}

			be.setStoc("Y");
			be.setStocDate(stocDate);
			purchaseBillItemDao.update(be);
			String providerName = "";
			Establishment est = (Establishment) purchaseBillItemDao.get(
					Establishment.class, b.getProviderId());
			if (est != null) {
				providerName = est.getEstName();
			}

			this.updateStock(b, purchaseBillItemDao.getList(b.getId()),
					stockDao, stockBalanceDao, idGenerator, be.getStocDate(),
					providerName, "STOC", ub.getStaffer().getStafferName());
		}

	}

	public void txUnStoc(HttpServletRequest request, long id,
			PurchaseBillItemDao purchaseBillItemDao, StockDao stockDao,
			StockBalanceDao stockBalanceDao, IdGenerator idGenerator,
			UserBean ub) throws Exception {
		PurchaseBill b = (PurchaseBill) purchaseBillItemDao.get(
				PurchaseBill.class, id);
		PurchaseBillExt be = (PurchaseBillExt) purchaseBillItemDao.get(
				PurchaseBillExt.class, id);
		if (b != null && be.getEnabled().equals("Y")
				&& be.getExamined().equals("Y") && be.getStoc().equals("Y")) {
			String priCode = "PURC_BUY_UN_STOC";
			if (b.getBillType().equals("BACK")) {
				priCode = "PURC_BACK_UN_STOC";
			}

			if (!EncCommonHelper.checkPrivilege(request, priCode)) {
				throw new Exception("Permission deny!");
			}

			be.setStoc("N");
			purchaseBillItemDao.update(be);
			String providerName = "";
			Establishment est = (Establishment) purchaseBillItemDao.get(
					Establishment.class, b.getProviderId());
			if (est != null) {
				providerName = est.getEstName();
			}

			this.updateStock(b, purchaseBillItemDao.getList(b.getId()),
					stockDao, stockBalanceDao, idGenerator, be.getStocDate(),
					providerName, "UN_STOC", ub.getStaffer().getStafferName());
		}

	}
}